#!/usr/bin/env python
import pygame
import time
from data.MapConst import *
import CollisionMap2d
import pickle
import Map
from game_engine.entity_manager.DoorEntity import DoorEntity
from game_engine.entity_manager.SpawnerEntity import SpawnerEntity
import game_engine.GameEngine
import render_engine.RenderEngine


class logger:

    def info(self,txt):
        print txt

class LevelManager:


        
    def __init__(self, resourceManager):
        
        self.WALLCOLOR = (198,226,255)
        self.m_Map = None
        self.m_Screen = None
        self.m_TileRow = 0
        self.m_TileCol = 0000
        self.logger = logger()
        self.m_debug = False
        self.m_tileFiles = {}
        self.m_resourceManager = resourceManager
        self.m_tileMap = {}
        self.m_mapMatrix = None
        self.m_tileXMax = 0
        self.m_tileYMax = 0
        self.m_entityCollisionMap = CollisionMap2d.CollisionMap2d()
        self.m_doorDict = {}
        self.m_entityCount = 0
        self.m_startPos = (2,2)
        self.m_currentLevel = 1



        #Wall Surfaces 
        self.m_VerticalWallSurface = None
        self.m_CornerWallSurface = None
        self.m_StandardTileSurface = None


        
        #Defined Tile Size
        self.m_TileSize = 30 



    #Load Tile Set
    def loadTileSet(self):

        # Load all the tile art
        self.m_tileMap = tileMap
        for (name, tile) in self.m_tileMap.items():
            fileName = tile["FILE"]
            img = self.m_resourceManager.loadImage("%s"%(fileName))
            demin = tile["DEMENSIONS"]
            tmpRect = pygame.Rect(tile["CORDS"],(demin))
            tile["SURFACE"] = img.subsurface(tmpRect)
            tile["SURFACE"] = pygame.transform.smoothscale(tile["SURFACE"],(self.m_TileSize, self.m_TileSize))
            self.m_resourceManager.registerImage(name, tile["SURFACE"])


    #Set Debug
    def setDebug(self,debug):
        self.m_debug = debug

    #Set out logger
    def setLogger(self,logger):
        self.logger = logger

    #Set our Tile Size
    def setTileSize(self,tileSize):
        self.m_TileSize = tileSize
        return
       
    #Get tile Size 
    def getTileSize(self):
        return self.m_TileSize       

    # Get level size
    def getLevelSize(self):
        return (self.m_tileXMax, self.m_tileYMax)

    # Get the entity collision map
    def getEntityCollisionMap(self):
        return self.m_entityCollisionMap

    def loadLevel(self,levelNbr):
        self.m_entityManager = game_engine.GameEngine.getGameEngine().getEntityManager()
        self.m_currentLevel = levelNbr

        # Clear all existing entities
        self.m_entityManager.unregisterAllEntitiesExceptPlayer()

        #Create our scene
        fd = open("maps/Level%s.goat" % (levelNbr), "rb")
        mapObj = pickle.loads(fd.read())

        #Get the size of our map and define our Matrix
        self.m_tileXMax = mapObj.m_MaxX +1 
        self.m_tileYMax = mapObj.m_MaxY +1 

        self.m_mapMatrix = [ [0 for row in range(self.m_tileYMax)] for col in range(self.m_tileXMax)]

        # Setup entity collision map
        print "Map width "+str(self.m_tileXMax)+" height "+str(self.m_tileYMax)
        self.m_entityCollisionMap.resize(self.m_tileXMax, self.m_tileYMax)
         
        #We need to convert our tile size to our map size in pixels
        self.m_MapSize = (self.m_tileXMax * self.m_TileSize , self.m_tileYMax * self.m_TileSize )

        #Lets load our tile set
        self.loadTileSet()


        #Create our surface for he map 
        self.m_MapSurface = pygame.Surface(self.m_MapSize)

        #self.m_MapSurface.fill((255,255,255))
        row = 0
        col = 0
        for tile in mapObj.getTiles():
            tileName = mapObj.getTiles()[tile]
            tileX = tile[0] * self.m_TileSize 
            tileY = tile[1] * self.m_TileSize
            # If tile has a START key, then this is the starting position
            if "START" in self.m_tileMap[tileName]:
                self.m_startPos=(tile[0], tile[1])

            #Add a door entity
            if "ENTITY" in self.m_tileMap[tileName]:
                self.m_entityCount += 1
                entityData = self.m_tileMap[tileName]["ENTITY"]
                entity = self.m_entityManager.spawnEntity(entityData["CLASS"], entityData["NAME"], entityData["SIZE"], entityData["ANIMATION"], entityData["IMAGE"], (tile[0], tile[1]), entityData["RENDER"])
                # Set custom attributes
                entity.setAttributes(entityData["ATTR"])


                # Entity here, draw the blank tile
                self.m_MapSurface.blit(self.m_tileMap["blank"]["SURFACE"],(tileX,tileY))


            else:
                self.m_MapSurface.blit(self.m_tileMap[tileName]["SURFACE"],(tileX,tileY))


            self.m_mapMatrix[tile[0]][tile[1]] = self.m_tileMap[tileName]["WALKABLE"]




        #If debug is set , lets draw our lines
        if(self.m_debug):
            self.logger.info("Drawing Lines") 

            #Draw our X
            for i in range(0,self.m_MapSize[1],self.m_TileSize):
                pygame.draw.line(self.m_MapSurface,(255,255,255),(1,i),(self.m_MapSize[0],i))
          
            #Draw our Y 
            for i in range(0,self.m_MapSize[0],self.m_TileSize):
                pygame.draw.line(self.m_MapSurface,(255,255,255),(i,1),(i,self.m_MapSize[1]))

        # Move the player to the starting position
        self.m_entityManager.getPlayerEntity().tryWarpTo(self.m_startPos[0], self.m_startPos[1], 1)

        return
        
    def isDoor(self,tileX,tileY):
        return self.m_doorDict.has_key(tileX,tileY)
             
    # Is a specific tile walkabl
    def isWalkable(self,tileX,tileY):
        # Can never walk out of bounds
        if tileX<0 or tileY<0 or tileX>=self.m_tileXMax or tileY>=self.m_tileYMax:
            return False
        return self.m_mapMatrix[tileX][tileY]

    # Is a specific tile walkable given an entity width/height
    def isEntityWalkable(self,entity,tileX,tileY):
        #print "Checking walkable on ", tileX, tileY
        (width, height) = entity.getSize()
        for w in range(width):
            for h in range(height):
                if self.isWalkable(tileX+w, tileY+h) == False:
                    #print "Cannot walk here"
                    return False
        # Can move all tiles this entity takes up
        return True

    def getCurrentLevel(self):
        return self.m_currentLevel

    # Our draw method
    def draw(self,surface,x,y):
        drawRect = pygame.Rect((x,y),surface.get_size())
        surface.blit(self.m_MapSurface,(0,0),drawRect)




if __name__ == "__main__":
    log = logger()
    log.info("Loading")

    lvlManager = LevelManager()
    lvlManager.setLogger(log)
    lvlManager.loadLevel(1)


    pygame.init()
    screen = pygame.display.set_mode((640,480),0,32)
    lvlManager.draw(pygame.display.get_surface())
    pygame.display.update()
    clock = pygame.time.Clock()
    pygame.display.flip()


    while(True):
        clock.tick(40)
        try:
            time.sleep(1)

        except KeyboardInterrupt:
            print "Done.."
            break

    











    



        





